package com.luxk.db.storage.impl;

import java.io.File;
import java.util.HashMap;

import com.luxk.db.common.ImpactException;
import com.luxk.db.errorcode.ErrorCodeStorage;
import com.luxk.db.storage.StorageGroup;
import com.luxk.db.storage.StorageUnit;

public class DefaultStorageGroup implements StorageGroup {
	
	private String name = null;
	private String path = null;
	private HashMap<String, StorageUnit> units =
			new HashMap<String, StorageUnit>();
	
	@Override
	public void mount(String[] paths) throws ImpactException {
		try {
			// 0번 path 하나만 사용
			File dir = new File(paths[0]);
			if(!dir.exists() || !dir.isDirectory()) {
				throw new ImpactException(ErrorCodeStorage.ERROR_INVALID_PATH,
						dir.getAbsolutePath());
				}
			this.name = dir.getName();
	
			File rawFiles[] = dir.listFiles();
			for(int i = 0; i < rawFiles.length; i++) {
				String unitName = rawFiles[i].getName();
				StorageUnit unit = new DefaultStorageUnit(this, unitName);
				unit.open();
				this.units.put(unitName, unit);
			}
		} catch(ImpactException e) {
			// 모든 StorageUnit을 close
			StorageUnit[] arr =
					(StorageUnit[])(this.units.values().toArray());
			for(StorageUnit ee: arr) {
				try { ee.close(); } catch(ImpactException eee) {}
			}
			units.clear();
			
			throw e;
		}
	}
	
	@Override
	public void unmount() throws ImpactException {
		// 모든 StorageUnit을 close
		StorageUnit[] arr =
				(StorageUnit[])(this.units.values().toArray());
		for(StorageUnit ee: arr) {
			try { ee.close(); } catch(ImpactException eee) {}
		}
		units.clear();
	}
	
	@Override
	public String getName() {
		return this.name;
	}
	
	@Override
	public StorageUnit createStorageUnit(String name) throws ImpactException {
		DefaultStorageUnit unit = new DefaultStorageUnit(this, name);
		unit.create(name, this.path);
		units.put(name, unit);
		return unit;
	}
	
	@Override
	public void dropStorageUnit(StorageUnit unit) throws ImpactException {
		((DefaultStorageUnit)unit).drop();
		this.units.remove(unit.getName());
	}

	@Override
	public StorageUnit getStorageUnit(String name) {
		return this.units.get(name);
	}
	
	@Override
	public StorageUnit[] getStorageUnitList() {
		return (StorageUnit[])this.units.values().toArray();
	}

	public void create(String name, String parentPath) throws ImpactException {
		File parent = new File(parentPath);
		if(!parent.exists() || !parent.isDirectory()) {
			throw new ImpactException(ErrorCodeStorage.ERROR_INVALID_PATH,
					parent.getAbsolutePath());
		}
		
		File me = new File(parent.getAbsolutePath() + File.separator + name);
		if(me.exists()) {
			if(!me.isDirectory()) {
				throw new ImpactException(ErrorCodeStorage.ERROR_NOT_DIRECTORY,
						me.getAbsolutePath());
			} else {
				return;
			}
		} else {
			if(!me.mkdir()) {
				throw new ImpactException(
						ErrorCodeStorage.ERROR_CREATE_DIRECTORY,
						me.getAbsolutePath());
			}
		}
		
		this.name = name;
	}
	
	public void drop() throws ImpactException {
		StorageUnit[] arr = getStorageUnitList();
		for(StorageUnit ee: arr) {
			try { dropStorageUnit(ee); } catch(ImpactException eee) {}
		}
		units.clear();
		
		File me = new File(this.path);
		if (!me.delete()) {
			throw new ImpactException(ErrorCodeStorage.ERROR_DELETE,
					me.getAbsolutePath());
		}
	}
	
	public String getAbsolutePath() {
		return this.path;
	}
}
